<?php
declare(strict_types=1);

namespace app\index\controller\api;

use lib\data\virtual\GoodsOrder;
use \Swoole\Http\Request;
use \Swoole\Http\Response;

use PDOException;
use sys\Log;
use Throwable;

class GoodsCashout {
    public \lib\User $user;
    public \lib\Merchant $merchant;
    public $middleware = [
        \lib\middleware\NetbarAuth::class=>[]
    ];

    public function withdrawal(Request $request, Response $response){
        $post = json_decode($request->getContent(), true);
        $checker = validate([
            'amount'=>'require|integer|min:1',
            'password'=>'require'
        ])->check($post);

        if(!$checker->pass()) return $checker->jsonSerialize();

        $mid = $this->merchant->id;
        $db = new \sys\Db();
        $syncObject = new \lib\sync\Synchronize($mid, $db);
        $merchant = \lib\Merchant::get($mid)->waitLock();

        if(empty($merchant->cashout_password) || $merchant->cashout_password != $post['password'])
            return ['success'=>false, 'message'=>'提现密码错误!'];
        
        if($merchant->amount_online < $post['amount'])
            return json(['success'=>false, 'message'=>'余额不足!']);

        $bank = $db->table('tp_nb_merchant_goods_bankcard')->where([['mid','=', $mid],['active','=', 1],['stage','=',2]])->find();
        if(!$bank)
            return json(['success'=>false, 'message'=>'提现账户设置出错!']);

        $ip = $request->header['x-real-ip'] ?? $request->server['remote_addr'];

        $time = time();
        $amount  = $post['amount'];
        $after = $merchant->amount_online - $amount;
        $tasks = [
            $tp_nb_goods_cashout_request = $db->task('tp_nb_goods_cashout_request')->subInsert([
                'mid'               => $mid,
                'src'               => GoodsOrder::PAY_SRC_ONLINE,
                'shift_id'          => $merchant->shift_id,
                'operator_uid'      => $this->user->id,         # 操作员ID
                'amount'            => $amount,                 # 提现金额
                'fee_amount'        => 0,                       # 手续费
                'recived_amount'    => $amount,                 # 商家到账的金额
                'rate'              => 0,                       # 提现费率
                'createtime'        => $time,                   # 提现时间
                'memo'              => [
                    'bank_type'         => $bank['bank_type'],
                    'bank_card'         => $bank['bank_card'],
                    'owner_bank'        => $bank['owner_bank'],
                    'owner_name'        => $bank['owner_name'],
                    'owner_idcard'      => $bank['owner_idcard']
                ],
                'ip'                => $ip,
                'stage'             => 0
            ]),
            $db->task('tp_nb_goods_order_flow')->subInsert([
                'mid'           => $mid,
                'shift_id'      => $merchant->shift_id,
                'order_type'    => \lib\data\virtual\GoodsCashout::ORDER_TYPE,
                'order_id'      => new \sys\db\ExpValue($tp_nb_goods_cashout_request->pkVarName()),
                'src'           => GoodsOrder::PAY_SRC_ONLINE,
                'isrc'          => 1,
                'amount'        => - $amount,
                'before'        => $merchant->amount_online,
                'after'         => $after,
                'createtime'    => $time,
            ]),
            
        ];

        if(null === ($changed = $merchant->update(['amount_online'=>$after], false, $oldValue))){
            return ['success'=>false, 'message'=>'提现失败,请联系万家工作人员!'];
        }
        $tasks[] = $db->table('tp_nb_merchant_goods')->where([['id','=',$mid]])->subUpdate($changed);

        $db->startTrans();
        try{
            if($db->batch_execute($tasks)){
                $db->commit();
                $syncObject->makeSyncTask($tasks);
                $syncObject->up('Merchant', $mid, ['amount_online'=>$after]);

                return ['success'=>true, 'message'=>'提现成功,请耐心等待工作人员处理!'];
            }
            $db->rollback();
        }catch(PDOException $e){
            Log::write(implode([$e->getMessage(),"\nFILE: ", $e->getFile(), "\nLINE: ", $e->getLine(),"\nTRACE: ", $e->getTraceAsString(),"\n"]),'ERROR');
            $db->rollback();
        }
        // 还原旧值
        $merchant->update($oldValue);

        return ['success'=>false, 'message'=>'提现失败,请联系万家工作人员!'];
    }
}